﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Xml;
using System.Xml.Xsl;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.XmlDiffPatch;

namespace Tests.Example1
{
    [TestClass]
    public class Transformations
    {
        [TestMethod]
        public void To_Html_Table()
        {
           
            string xsl = "Tests.Example1.Docs.CatalogToHtmlTable.xslt";
            string xml = "Tests.Example1.Docs.Catalog.xml";
            var expectedHtml = this.GetType().Assembly.RetrieveTextByName("Tests.Example1.Docs.Catalog.html");
            var actualHtml = Transform(xsl, xml);

             AssertAreXmlEqual(expectedHtml, actualHtml);
        }



        [TestMethod]
        public void To_Html_Table2()
        {

            string xsl = "Tests.Example1.Docs.CatalogToHtmlTable2.xslt";
            string xml = "Tests.Example1.Docs.Catalog.xml";
            var expectedHtml = this.GetType().Assembly.RetrieveTextByName("Tests.Example1.Docs.Catalog.html");
            var actualHtml = Transform(xsl, xml);

            AssertAreXmlEqual(expectedHtml, actualHtml);
        }



        [TestMethod]
        public void To_Html_Table3()
        {

            string xsl = "Tests.Example1.Docs.CatalogToHtmlTable3.xslt";
            string xml = "Tests.Example1.Docs.Catalog.xml";
            var expectedHtml = this.GetType().Assembly.RetrieveTextByName("Tests.Example1.Docs.Catalog.html");
            var actualHtml = Transform(xsl, xml);

            AssertAreXmlEqual(expectedHtml, actualHtml);
        }


        private static void AssertAreXmlEqual(string expectedHtml, string actualHtml)
        {
            bool identical = false;
            string diff = String.Empty;
            XmlDiff xmldiff =
                new XmlDiff(XmlDiffOptions.IgnoreChildOrder | XmlDiffOptions.IgnoreNamespaces | XmlDiffOptions.IgnorePrefixes);

         
            XmlDocument expected = new XmlDocument();
            expected.LoadXml(expectedHtml);

            XmlDocument actual = new XmlDocument();
            actual.LoadXml(actualHtml);
            using (var mStream = new MemoryStream())
            {
                var writerSettings = new XmlWriterSettings();
                writerSettings.OmitXmlDeclaration = true;
                writerSettings.Indent = true;
                using (XmlWriter writer = XmlWriter.Create(mStream, writerSettings))
                {
                 
                    if (writer.Settings != null)
                    {
                        identical = xmldiff.Compare(expected.DocumentElement, actual.DocumentElement, writer);

                        writer.Flush();
                    }
                }

                mStream.Position = 0;
                using (var sr = new StreamReader(mStream))
                {
                    diff = sr.ReadToEnd();
                }
            }

            if (!identical)
            {
                Console.WriteLine(diff);
                Assert.Fail("Expected != actual");
            
            }
            else
            {
                Assert.IsTrue(1==1);
            }

        }

        private string Transform(string xsl, string xml)
        {
            string html = String.Empty;
            using (
                var xslstream =
                    this.GetType().Assembly.RetrieveStreamByName(xsl))
            {
                using (var xslReader = new XmlTextReader(xslstream))
                {
                    using (
                        var xmlstream =
                            this.GetType().Assembly.RetrieveStreamByName(xml))
                    {
                        using (var xmlReader = new XmlTextReader(xmlstream))
                        {
                            using (var mStream = new MemoryStream())
                            {
                                   var writerSettings = new XmlWriterSettings();
                                writerSettings.OmitXmlDeclaration = true;
                                        writerSettings.Indent = true;
                                        using (XmlWriter writer = XmlWriter.Create(mStream, writerSettings))
                                {
                                    if (writer.Settings != null)
                                    {
                                     
                                    
                                        var myXslTrans = new XslCompiledTransform();

                                        myXslTrans.Load(xslReader);
                                        myXslTrans.Transform(xmlReader, writer);

                                        writer.Flush();
                                    }
                                 
                                }

                                mStream.Position = 0;
                                using (var sr = new StreamReader(mStream))
                                {
                                    html = sr.ReadToEnd();
                                }
                            }
                        }
                    }
                }
                return html;
            }




        }
    }
}
